package com.fly.demo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Java从8开始，不但引入了Lambda表达式，还引入了一个全新的流式API：Stream API。它位于java.util.stream包中。
 *
 * 划重点：这个Stream不同于java.io的InputStream和OutputStream，它代表的是任意Java对象的序列。
 *
 * Stream API的基本用法就是：创建一个Stream，然后做若干次转换，最后调用一个求值方法获取真正计算的结果：
 *
 * 把数组变成Stream使用Arrays.stream()方法。对于Collection（List、Set、Queue等），直接调用stream()方法就可以获得Stream。
 */
public class TheStream1
{
    public static void main(String[] args)
    {
        int[] arrayInt1 = {1, 3, 5, 2, 4, 8, 6, 0, 9};
        
        /**
         * 1.Stream总案例 Stream API的基本用法就是：创建一个Stream，然后做若干次转换，最后调用一个求值方法获取真正计算的结果
         */
        int result = Arrays.stream(arrayInt1) // 创建Stream
                .filter(n -> n % 2 == 0) // 任意个转换
                .map(n -> n * n) // 任意个转换
                .limit(100) // 任意个转换
                .sum(); // 最终计算结果
        
        /**
         * 2.Stream创建 把数组变成Stream使用Arrays.stream()方法。 对于Collection（List、Set、Queue等），直接调用stream()方法就可以获得Stream。
         */
        int[] arrayInt2 = {1, 2, 4, 5, 6, 7, 8, 9};
        Arrays.stream(arrayInt2);// 数组变成Stream
        
        List<String> listStr = new ArrayList<>();
        listStr.add("hello");
        listStr.add("world");
        listStr.stream();// list转stream
        
        /**
         * 3.Stream.map() Stream.map()是Stream最常用的一个转换方法，它把一个Stream转换为另一个Stream 所谓map操作，就是把一种操作运算，映射到一个序列的每一个元素上。 例如，对x计算它的平方，可以使用函数f(x) = x * x。我们把这个函数映射到一个序列1，2，3，4，5上，就得到了另一个序列1，4，9，16，25：
         */
        int[] arrayInt3 = {1, 2, 3, 4, 5};
        int[] result1 = Arrays.stream(arrayInt3).map(n -> n * n).toArray();// 将arrayInt3数组先转为Stream,再平方后再转为数组
        
        List<Integer> list1 = new ArrayList<>();
        list1.add(100);
        list1.add(200);
        List<Integer> list2 = list1.stream().map(n -> n * 2).collect(Collectors.toList());// 将list1列表先转为Stream,再*2后再转为List
        
        /**
         * 4.Stream.filter() 所谓filter()操作，就是对一个Stream的所有元素一一进行测试，不满足条件的就被“滤掉”了，剩下的满足条件的元素就构成了一个新的Stream。
         */
        int[] arrayInt4 = {1, 2, 3, 4, 5};
        int[] result2 = Arrays.stream(arrayInt4).filter(n -> n % 2 == 0).toArray();// 通过filter()过滤出偶数
        
        List<String> list3 = new ArrayList<>();
        list3.add("apple");
        list3.add("banana");
        list3.add("pear");
        list3.add("peach");
        list3.stream().filter(n -> n.startsWith("p")).collect(Collectors.toList());// 通过filter()过滤出以p开头的字符串
        list3.stream().filter(n -> n.contains("e")).collect(Collectors.toList());// 通过filter()过滤出包含e的字符串
        
        /**
         * 5.forEach() 循环每一个元素
         */
        int[] arrayInt5 = {1, 2, 3, 4, 5};
        Arrays.stream(arrayInt5).forEach(System.out::println);// 循环输出元素
        
        /**
         * 6.limit() 它是用于限制流中元素的个数，即取前n个元素，返回新的流
         */
        int[] arrayInt6 = {1, 2, 3, 4, 5};
        Arrays.stream(arrayInt5).limit(3).toArray();// 取出前3个元素并将该stream转为数组
        
        /**
         * 7其余方法 其余很多方法如下，只列出了部分了方法
         */
        int[] arrayInt7 = {1, 2, 3, 4, 5};
        Arrays.stream(arrayInt7).sum();// 求和
        Arrays.stream(arrayInt7).average();// 求平均数
        Arrays.stream(arrayInt7).count();// 统计
        
        /**
         * 8.stream类型转其他类型 stream可转换为Array、list、set、String等， 转Array:".toArray()" 转List:".collect(Collectors.toList())" 转Set:".collect(Collectors.toSet())" 转String:".toString()"
         *
         */
        
    }
}
